﻿@using Radzen
@using System.Linq
@using System.Linq.Dynamic.Core
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.JSInterop
@using Microsoft.AspNetCore.Components.Rendering
@typeparam TValue
@inherits DropDownBase<TValue>

@if (Visible)
{
    <div @ref="@Element" @attributes="Attributes" class="@GetCssClass()" @onmousedown="@(args => OpenPopup("ArrowDown", false, true))" style="@Style" tabindex="@TabIndex"
         @onkeydown="@((args) => OnKeyPress(args))" id="@GetId()">
        <div class="rz-helper-hidden-accessible">
            <input disabled="@Disabled" style="width:100%" aria-haspopup="listbox" readonly="" type="text" tabindex="-1"
                   name="@Name" value="@(Value != null ? Value : "")"
                   aria-label="@(!Multiple && Value != null ? PropertyAccess.GetItemOrValueFromProperty(Value, TextProperty) : "")" />
        </div>

        @if (Template != null && selectedItem != null)
        {
            <label class="rz-dropdown-label rz-inputtext ">
                @Template(selectedItem)
            </label>
        }
        else if (selectedItem != null)
        {
            <label class="rz-dropdown-label rz-inputtext ">
                @PropertyAccess.GetItemOrValueFromProperty(selectedItem, TextProperty)
            </label>
        }
        else if (selectedItems.Count > 0)
        {
            <label class="rz-dropdown-label rz-inputtext ">
                @if (selectedItems.Count < MaxSelectedLabels)
                {
                    @if (Template == null)
                    {
                        @(string.Join(",", selectedItems.Select(i => PropertyAccess.GetItemOrValueFromProperty(i, TextProperty))))
                    }
                    else
                    {
                        foreach (var item in selectedItems)
                        {
                            @Template(item)@(",")
                        }
                    }
                }
                else
                {
                    @($"{selectedItems.Count} {SelectedItemsText}")
                }
            </label>
        }
        else if (!string.IsNullOrEmpty(Placeholder))
        {
            <label class="rz-dropdown-label rz-inputtext  rz-placeholder">
                @Placeholder
            </label>
        }
        else
        {
            <label class="rz-dropdown-label rz-inputtext ">
                &nbsp;
            </label>
        }

        <div class="rz-dropdown-trigger  rz-corner-right">
            <span class="rz-dropdown-trigger-icon  rzi rzi-chevron-down"></span>
        </div>

        <div id="@PopupID" class="@(Multiple ? "rz-multiselect-panel    " : "rz-dropdown-panel    ")"
             style="display:none; box-sizing: border-box">
            @if (AllowFiltering && !Multiple)
            {
                <div class="rz-dropdown-filter-container">
                    <input id="@SearchID" @ref="@search" tabindex="@TabIndex" class="rz-dropdown-filter rz-inputtext   " autocomplete="off" type="text"
                           @onchange="@((ChangeEventArgs args) => OnFilter(args))" @onkeydown="@((args) => OnFilterKeyPress(args))" value="@searchText" />
                    <span class="rz-dropdown-filter-icon rzi rzi-search"></span>
                </div>
            }
            @if (Multiple)
            {
                <div class=" rz-multiselect-header rz-helper-clearfix" @onclick="@SelectAll" @onclick:preventDefault>
                    <div class="rz-chkbox" title="@(!AllowFiltering ? "" : SelectAllText)">
                        <div class="rz-helper-hidden-accessible">
                            <input readonly="readonly" type="checkbox">
                        </div>
                        <div class="@(View != null && selectedItems.Count == View.Cast<object>().Count() ? "rz-chkbox-box    rz-state-active" : "rz-chkbox-box   ")">
                            <span class="@(View != null && selectedItems.Count == View.Cast<object>().Count() ? "rz-chkbox-icon  rzi rzi-check" : "rz-chkbox-icon ")"></span>
                        </div>
                    </div>
                    @if (!AllowFiltering && !string.IsNullOrEmpty(SelectAllText))
                    {
                        @SelectAllText
                    }
                    @if (AllowFiltering)
                    {
                        <div class="rz-multiselect-filter-container">
                            <input id="@SearchID" tabindex="@TabIndex" class="rz-inputtext" role="textbox" type="text"
                                   onclick="Radzen.preventDefaultAndStopPropagation(event)"
                                   @ref="@search"
                                   @onchange="@((args) => OnFilter(args))" @onkeydown="@((args) => OnFilterKeyPress(args))" value="@searchText" />
                            <span class="rz-multiselect-filter-icon rzi rzi-search"></span>
                        </div>
                    }
                    <a class="rz-multiselect-close " @onclick="@ClearAll" @onclick:stopPropagation="true">
                        <span class="rzi rzi-times"></span>
                    </a>
                </div>
            }
            <div class="@(Multiple ? "rz-multiselect-items-wrapper" : "rz-dropdown-items-wrapper")" style="max-height: 200px;overflow-x: hidden">
                <ul @ref="list" class="@(Multiple ? "rz-multiselect-items rz-multiselect-list    " : "rz-dropdown-items rz-dropdown-list    ")" role="listbox">
                    @if (View != null)
                    {
                        @RenderItems()
                    }
                </ul>
            </div>
        </div>
        @if (AllowClear && (!Multiple && HasValue || Multiple && selectedItems.Count > 0))
        {
            <i class="rz-dropdown-clear-icon rzi rzi-times" @onclick="@ClearAll" @onclick:stopPropagation="true"></i>
        }
    </div>
}
@code {
    internal override void RenderItem(RenderTreeBuilder builder, object item)
    {
        builder.OpenComponent(0, typeof(RadzenDropDownItem<TValue>));
        builder.AddAttribute(1, "DropDown", this);
        builder.AddAttribute(2, "Item", item);
        builder.SetKey(item);
        builder.CloseComponent();
    }

    [Parameter]
    public int MaxSelectedLabels { get; set; } = 4;

    [Parameter]
    public string SelectedItemsText { get; set; } = "items selected";

    [Parameter]
    public string SelectAllText { get; set; }

    private bool visibleChanged = false;
    private bool disabledChanged = false;
    private bool firstRender = true;

    public override async Task SetParametersAsync(ParameterView parameters)
    {
        visibleChanged = parameters.DidParameterChange(nameof(Visible), Visible);
        disabledChanged = parameters.DidParameterChange(nameof(Disabled), Disabled);

        await base.SetParametersAsync(parameters);

        if (visibleChanged && !firstRender)
        {
            if (Visible == false)
            {
                Dispose();
            }
        }
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);

        this.firstRender = firstRender;

        if (firstRender || visibleChanged || disabledChanged)
        {
            visibleChanged = false;
            disabledChanged = false;

            if (Visible)
            {
                bool reload = false;
                if (LoadData.HasDelegate && Data == null)
                {
                    await LoadData.InvokeAsync(await GetLoadDataArgs());
                    reload = true;
                }

                if (!Disabled)
                {
                    await JSRuntime.InvokeVoidAsync("Radzen.preventArrows", Element);
                    reload = true;
                }

                if (reload)
                {
                    StateHasChanged();
                }
            }
        }
    }

    protected override async System.Threading.Tasks.Task OnSelectItem(object item, bool isFromKey = false)
    {
        if (!Multiple && !isFromKey)
        {
            await JSRuntime.InvokeVoidAsync("Radzen.closePopup", PopupID);
        }

        await SelectItem(item);
    }

    internal async System.Threading.Tasks.Task OnSelectItemInternal(object item, bool isFromKey = false)
    {
        await OnSelectItem(item, isFromKey);
    }

    protected override string GetComponentCssClass()
    {
        var classList = new List<string>();

        classList.Add("rz-dropdown");

        if (FieldIdentifier.FieldName != null && EditContext != null)
        {
            classList.Add(EditContext?.FieldCssClass(FieldIdentifier));
        }

        if (Disabled)
        {
            classList.Add("rz-state-disabled");
        }

        if (AllowClear)
        {
            classList.Add("rz-clear");
        }

        return String.Join(" ", classList);
    }

    private string ClosePopupScript()
    {
        if (Disabled)
        {
            return string.Empty;
        }

        return $"Radzen.closePopup('{PopupID}')";
    }

    public override void Dispose()
    {
        base.Dispose();

        if (IsJSRuntimeAvailable)
        {
            JSRuntime.InvokeVoidAsync("Radzen.destroyPopup", PopupID);
        }
    }

    internal async System.Threading.Tasks.Task ClosePopup()
    {
        await JSRuntime.InvokeVoidAsync("Radzen.closePopup", PopupID);
    }
}